<template>
  <div class="fill-height">
    <!-- 页面标题 -->
    <div class="page-header">
      <div class="header-content">
        <h1 class="page-title">
          <el-icon class="title-icon"><Cpu /></el-icon>
          执行器运行情况
        </h1>
        <el-space>
          <el-button
            type="primary"
            @click="loadOverviewData"
            :loading="overviewLoading"
          >
            <el-icon><Refresh /></el-icon>
            刷新概览
          </el-button>
          <el-button
            type="warning"
            @click="cleanOfflineExecutors"
            :loading="cleanLoading"
          >
            <el-icon><Delete /></el-icon>
            清理离线执行器
          </el-button>
        </el-space>
      </div>
    </div>

    <!-- 概览统计卡片 -->
    <el-row :gutter="16" class="overview-cards">
      <el-col :span="6">
        <div class="stat-card">
          <div class="stat-icon">
            <el-icon><Cpu /></el-icon>
          </div>
          <div class="stat-content">
            <div class="stat-number">{{ overviewData.totalExecutors || 0 }}</div>
            <div class="stat-label">总执行器数</div>
          </div>
        </div>
      </el-col>
      <el-col :span="6">
        <div class="stat-card">
          <div class="stat-icon online">
            <el-icon><Connection /></el-icon>
          </div>
          <div class="stat-content">
            <div class="stat-number">{{ overviewData.onlineExecutors || 0 }}</div>
            <div class="stat-label">在线执行器</div>
          </div>
        </div>
      </el-col>
      <el-col :span="6">
        <div class="stat-card">
          <div class="stat-icon warning">
            <el-icon><Warning /></el-icon>
          </div>
          <div class="stat-content">
            <div class="stat-number">{{ overviewData.totalActiveThreads || 0 }}</div>
            <div class="stat-label">活跃线程数</div>
          </div>
        </div>
      </el-col>
      <el-col :span="6">
        <div class="stat-card">
          <div class="stat-icon success">
            <el-icon><DataAnalysis /></el-icon>
          </div>
          <div class="stat-content">
            <div class="stat-number">{{ overviewData.totalRunningTasks || 0 }}</div>
            <div class="stat-label">运行中任务</div>
          </div>
        </div>
      </el-col>
    </el-row>

    <!-- 图表区域 -->
    <el-row :gutter="16" class="chart-section">
      <el-col :span="12">
        <el-card class="chart-card" header="执行器状态分布">
          <v-chart :option="statusChartOption" style="height: 300px" />
        </el-card>
      </el-col>
      <el-col :span="12">
        <el-card class="chart-card" header="应用分布统计">
          <v-chart :option="appChartOption" style="height: 300px" />
        </el-card>
      </el-col>
    </el-row>

    <!-- 搜索和过滤区域 -->
    <el-card class="search-card" header="搜索条件">
      <el-row :gutter="16">
        <el-col :span="6">
          <el-input
            v-model="searchForm.registerKey"
            placeholder="执行器标识"
            clearable
          />
        </el-col>
        <el-col :span="6">
          <el-input
            v-model="searchForm.appName"
            placeholder="应用名称"
            clearable
          />
        </el-col>
        <el-col :span="6">
          <el-select
            v-model="searchForm.status"
            placeholder="状态筛选"
            clearable
            style="width: 100%"
          >
            <el-option label="在线" value="online" />
            <el-option label="离线" value="offline" />
            <el-option label="健康" value="healthy" />
            <el-option label="警告" value="warning" />
            <el-option label="错误" value="error" />
          </el-select>
        </el-col>
        <el-col :span="6">
          <el-space>
            <el-button
              type="primary"
              @click="loadExecutorList"
              :loading="loading"
            >
              <el-icon><Search /></el-icon>
              搜索
            </el-button>
            <el-button @click="resetSearch">
              <el-icon><Refresh /></el-icon>
              重置
            </el-button>
          </el-space>
        </el-col>
      </el-row>
    </el-card>

    <!-- 执行器列表 -->
    <el-card class="table-card" header="执行器列表">
      <template #header>
        <div class="card-header">
          <span>执行器列表</span>
          <el-button
            type="primary"
            @click="refreshList"
            :loading="loading"
          >
            <el-icon><Refresh /></el-icon>
            刷新
          </el-button>
        </div>
      </template>

      <el-table
        :data="executorList"
        :loading="loading"
        style="width: 100%"
        row-key="registerKey"
        size="default"
        @row-click="handleRowClick"
      >
        <el-table-column prop="registerKey" label="执行器标识" width="200" />
        <el-table-column prop="appName" label="应用名称" width="150" />
        <el-table-column prop="status" label="状态" width="100">
          <template #default="{ row }">
            <el-tag :type="getStatusType(row.status)">
              {{ row.statusDesc }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="currentPoolSize" label="线程池大小" width="120" />
        <el-table-column prop="currentActiveCount" label="活跃线程" width="120" />
        <el-table-column prop="currentQueueSize" label="队列大小" width="120" />
        <el-table-column prop="currentRunningTasks" label="运行任务" width="120" />
        <el-table-column prop="currentMemoryUsagePercent" label="内存使用率" width="120">
          <template #default="{ row }">
            <el-progress
              :percentage="row.currentMemoryUsagePercent"
              :color="getMemoryColor(row.currentMemoryUsagePercent)"
              :stroke-width="8"
            />
          </template>
        </el-table-column>
        <el-table-column prop="uptimeSeconds" label="运行时间" width="120">
          <template #default="{ row }">
            {{ formatUptime(row.uptimeSeconds) }}
          </template>
        </el-table-column>
        <el-table-column prop="lastHeartbeatTime" label="最后心跳" width="180">
          <template #default="{ row }">
            {{ formatDateTime(row.lastHeartbeatTime) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="120" fixed="right">
          <template #default="{ row }">
            <el-button
              type="primary"
              size="small"
              @click.stop="viewEnvironmentMonitor(row)"
            >
              <el-icon><View /></el-icon>
              环境监控
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="pagination.pageNum"
          v-model:page-size="pagination.pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :total="pagination.total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  Cpu, Refresh, Delete, Connection, Warning, DataAnalysis,
  Search, View
} from '@element-plus/icons-vue'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { PieChart, BarChart } from 'echarts/charts'
import { TitleComponent, TooltipComponent, LegendComponent, GridComponent } from 'echarts/components'
import VChart from 'vue-echarts'
import { executorRuntimeApi } from '@/services/api'
import type {
  ExecutorRuntimeQueryDTO, ExecutorRuntimeVO, ExecutorRuntimeOverviewVO,
  ApiResult, PageResult
} from '@/types/job'

// 注册 ECharts 组件
use([CanvasRenderer, PieChart, BarChart, TitleComponent, TooltipComponent, LegendComponent, GridComponent])

const router = useRouter()

// 响应式数据
const loading = ref(false)
const overviewLoading = ref(false)
const cleanLoading = ref(false)
const executorList = ref<ExecutorRuntimeVO[]>([])
const overviewData = ref<ExecutorRuntimeOverviewVO>({
  totalExecutors: 0,
  onlineExecutors: 0,
  offlineExecutors: 0,
  healthyExecutors: 0,
  warningExecutors: 0,
  errorExecutors: 0,
  totalActiveThreads: 0,
  totalRunningTasks: 0,
  averageMemoryUsage: 0,
  averageQueueUsage: 0,
  statusDistribution: [],
  appDistribution: [],
  recentActiveExecutors: []
})

// 搜索表单
const searchForm = reactive<ExecutorRuntimeQueryDTO>({
  registerKey: '',
  appName: '',
  status: '',
  pageNum: 1,
  pageSize: 10
})

// 分页信息
const pagination = reactive({
  pageNum: 1,
  pageSize: 10,
  total: 0
})

// 状态分布图表配置
const statusChartOption = computed(() => {
  const data = overviewData.value.statusDistribution || []
  // 如果statusDistribution是数组，取第一个元素；如果是单个对象，直接使用
  const statusData = Array.isArray(data) ? (data[0] || {}) : data
  return {
    title: {
      text: '执行器状态分布',
      left: 'center',
      textStyle: {
        fontSize: 16,
        fontWeight: 'bold'
      }
    },
    tooltip: {
      trigger: 'item',
      formatter: '{a} <br/>{b}: {c} ({d}%)'
    },
    legend: {
      orient: 'vertical',
      left: 'left',
      data: ['正常', '警告', '错误', '离线']
    },
    series: [
      {
        name: '执行器状态',
        type: 'pie',
        radius: '50%',
        data: [
          { value: statusData.normalCount || 0, name: '正常', itemStyle: { color: '#67C23A' } },
          { value: statusData.warningCount || 0, name: '警告', itemStyle: { color: '#E6A23C' } },
          { value: statusData.errorCount || 0, name: '错误', itemStyle: { color: '#F56C6C' } },
          { value: statusData.offlineCount || 0, name: '离线', itemStyle: { color: '#909399' } }
        ],
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: 'rgba(0, 0, 0, 0.5)'
          }
        }
      }
    ]
  }
})

// 应用分布图表配置
const appChartOption = computed(() => {
  const data = overviewData.value.appDistribution || []
  return {
    title: {
      text: '应用分布统计',
      left: 'center',
      textStyle: {
        fontSize: 16,
        fontWeight: 'bold'
      }
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    },
    legend: {
      data: ['执行器数量', '总任务数', '完成任务数']
    },
    xAxis: {
      type: 'category',
      data: data.map(item => item.appName)
    },
    yAxis: {
      type: 'value'
    },
    series: [
      {
        name: '执行器数量',
        type: 'bar',
        data: data.map(item => item.executorCount),
        itemStyle: { color: '#409EFF' }
      },
      {
        name: '总任务数',
        type: 'bar',
        data: data.map(item => item.totalTasks),
        itemStyle: { color: '#67C23A' }
      },
      {
        name: '完成任务数',
        type: 'bar',
        data: data.map(item => item.completedTasks),
        itemStyle: { color: '#E6A23C' }
      }
    ]
  }
})

// 获取状态类型
const getStatusType = (status: string) => {
  switch (status) {
    case 'online':
    case 'healthy':
      return 'success'
    case 'warning':
      return 'warning'
    case 'error':
      return 'danger'
    case 'offline':
      return 'info'
    default:
      return 'info'
  }
}

// 获取内存使用率颜色
const getMemoryColor = (usage: number) => {
  if (usage < 60) return '#67C23A'
  if (usage < 80) return '#E6A23C'
  return '#F56C6C'
}

// 格式化运行时间
const formatUptime = (seconds: number) => {
  const days = Math.floor(seconds / 86400)
  const hours = Math.floor((seconds % 86400) / 3600)
  const minutes = Math.floor((seconds % 3600) / 60)

  if (days > 0) return `${days}天${hours}小时`
  if (hours > 0) return `${hours}小时${minutes}分钟`
  return `${minutes}分钟`
}

// 格式化日期时间
const formatDateTime = (dateTime: string) => {
  if (!dateTime) return '-'
  return new Date(dateTime).toLocaleString()
}

// 加载概览数据
const loadOverviewData = async () => {
  overviewLoading.value = true
  try {
    const response: ApiResult<ExecutorRuntimeOverviewVO> = await executorRuntimeApi.getRuntimeOverview()
    if (response.success) {
      overviewData.value = response.data
    } else {
      ElMessage.error('加载概览数据失败: ' + response.message)
    }
  } catch (error) {
    console.error('加载概览数据出错:', error)
    ElMessage.error('加载概览数据出错')
  } finally {
    overviewLoading.value = false
  }
}

// 加载执行器列表
const loadExecutorList = async () => {
  loading.value = true
  try {
    const params: ExecutorRuntimeQueryDTO = {
      ...searchForm,
      pageNum: pagination.pageNum,
      pageSize: pagination.pageSize
    }

    const response: ApiResult<PageResult<ExecutorRuntimeVO>> = await executorRuntimeApi.queryExecutorRuntime(params)
    if (response.success) {
      executorList.value = response.data.records
      pagination.total = response.data.total
    } else {
      ElMessage.error('加载执行器列表失败: ' + response.message)
    }
  } catch (error) {
    console.error('加载执行器列表出错:', error)
    ElMessage.error('加载执行器列表出错')
  } finally {
    loading.value = false
  }
}

// 重置搜索
const resetSearch = () => {
  searchForm.registerKey = ''
  searchForm.appName = ''
  searchForm.status = ''
  pagination.pageNum = 1
  loadExecutorList()
}

// 刷新列表
const refreshList = () => {
  loadExecutorList()
}

// 处理分页大小变化
const handleSizeChange = (size: number) => {
  pagination.pageSize = size
  pagination.pageNum = 1
  loadExecutorList()
}

// 处理当前页变化
const handleCurrentChange = (page: number) => {
  pagination.pageNum = page
  loadExecutorList()
}

// 处理行点击
const handleRowClick = (row: ExecutorRuntimeVO) => {
  console.log('点击执行器:', row)
}

// 查看环境监控
const viewEnvironmentMonitor = (row: ExecutorRuntimeVO) => {
  router.push(`/environment-monitor/${row.registerKey}`)
}

// 清理离线执行器
const cleanOfflineExecutors = async () => {
  try {
    await ElMessageBox.confirm(
      '确定要清理离线执行器状态吗？这将清理30分钟前的离线执行器记录。',
      '确认清理',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )

    cleanLoading.value = true
    const response: ApiResult<void> = await executorRuntimeApi.cleanOfflineExecutors(30)
    if (response.success) {
      ElMessage.success('清理离线执行器成功')
      loadOverviewData()
      loadExecutorList()
    } else {
      ElMessage.error('清理离线执行器失败: ' + response.message)
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error('清理离线执行器出错:', error)
      ElMessage.error('清理离线执行器出错')
    }
  } finally {
    cleanLoading.value = false
  }
}

// 页面加载时执行
onMounted(() => {
  loadOverviewData()
  loadExecutorList()
})
</script>

<style scoped>
/* 页面布局 */
.fill-height {
  min-height: 100vh;
  padding: 20px;
  background: #f5f7fa;
}

/* 页面标题 */
.page-header {
  margin-bottom: 20px;
}

.header-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.page-title {
  display: flex;
  align-items: center;
  font-size: 24px;
  font-weight: 600;
  color: #1e293b;
  margin: 0;
}

.title-icon {
  margin-right: 12px;
  font-size: 28px;
  color: #3b82f6;
}

/* 概览卡片 */
.overview-cards {
  margin-bottom: 20px;
}

.stat-card {
  background: #ffffff;
  border: 2px solid #e2e8f0;
  border-radius: 0;
  padding: 20px;
  display: flex;
  align-items: center;
  box-shadow: 0 2px 8px rgba(30, 58, 138, 0.1);
  position: relative;
  overflow: hidden;
}

.stat-card::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 0 30px 30px 0;
  border-color: transparent #3b82f6 transparent transparent;
}

.stat-icon {
  width: 60px;
  height: 60px;
  border-radius: 0;
  background: #f1f5f9;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 16px;
  font-size: 24px;
  color: #64748b;
}

.stat-icon.online {
  background: #dcfce7;
  color: #16a34a;
}

.stat-icon.warning {
  background: #fef3c7;
  color: #d97706;
}

.stat-icon.success {
  background: #dbeafe;
  color: #2563eb;
}

.stat-content {
  flex: 1;
}

.stat-number {
  font-size: 28px;
  font-weight: 700;
  color: #3b82f6;
  line-height: 1;
  margin-bottom: 4px;
}

.stat-label {
  font-size: 14px;
  color: #64748b;
  font-weight: 500;
}

/* 图表区域 */
.chart-section {
  margin-bottom: 20px;
}

.chart-card {
  border: 2px solid #e2e8f0;
  border-radius: 0;
  box-shadow: 0 2px 8px rgba(30, 58, 138, 0.1);
}

/* 搜索卡片 */
.search-card {
  margin-bottom: 20px;
  border: 2px solid #e2e8f0;
  border-radius: 0;
  box-shadow: 0 2px 8px rgba(30, 58, 138, 0.1);
}

/* 表格卡片 */
.table-card {
  border: 2px solid #e2e8f0;
  border-radius: 0;
  box-shadow: 0 2px 8px rgba(30, 58, 138, 0.1);
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* 现代化表格样式 */
.el-table {
  border: 2px solid #cbd5e1;
  border-radius: 0;
  box-shadow: 0 4px 12px rgba(30, 58, 138, 0.1);
  position: relative;
  overflow: hidden;
}

/* 表头样式 */
.el-table :deep(.el-table__header-wrapper) {
  background: #f1f5f9;
}

.el-table :deep(.el-table__header) {
  background: #f1f5f9;
}

.el-table :deep(.el-table__header th) {
  background: #f1f5f9 !important;
  color: #475569;
  font-weight: 600;
  font-size: 14px;
  padding: 16px 12px;
  border-bottom: 2px solid #cbd5e1;
  border-right: 1px solid #cbd5e1;
  text-align: left;
  position: relative;
}

.el-table :deep(.el-table__header th:last-child) {
  border-right: none;
}

/* 表格内容样式 */
.el-table :deep(.el-table__body-wrapper) {
  background: #ffffff;
}

.el-table :deep(.el-table__body tr) {
  background: #ffffff;
  transition: background-color 0.2s ease;
  cursor: pointer;
}

/* 隔行换色 */
.el-table :deep(.el-table__body tr:nth-child(even)) {
  background: #f8fafc;
}

.el-table :deep(.el-table__body tr:hover) {
  background: #e3f2fd !important;
}

/* 单元格样式 */
.el-table :deep(.el-table__body td) {
  padding: 16px 12px;
  border-bottom: 1px solid #e2e8f0;
  border-right: 1px solid #e2e8f0;
  font-size: 14px;
  color: #1e293b;
  text-align: left;
  position: relative;
}

.el-table :deep(.el-table__body td:last-child) {
  border-right: none;
}


/* 状态标签样式 */
.el-table :deep(.el-tag) {
  border-radius: 0;
  font-weight: 600;
  padding: 4px 8px;
  border: 1px solid;
  position: relative;
}

.el-table :deep(.el-tag--success) {
  background: #e8f5e8;
  border-color: #4caf50;
  color: #2e7d32;
}

.el-table :deep(.el-tag--warning) {
  background: #fff8e1;
  border-color: #ff9800;
  color: #f57c00;
}

.el-table :deep(.el-tag--danger) {
  background: #ffebee;
  border-color: #f44336;
  color: #c62828;
}

.el-table :deep(.el-tag--info) {
  background: #e3f2fd;
  border-color: #2196f3;
  color: #1565c0;
}

/* 进度条样式 */
.el-table :deep(.el-progress) {
  margin: 0;
}

.el-table :deep(.el-progress__text) {
  font-size: 12px;
  color: #64748b;
}

/* 分页容器 */
.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: center;
}

/* 按钮样式 */
.el-button {
  border-radius: 0;
  font-weight: 600;
  border: 2px solid;
  transition: all 0.3s ease;
}

.el-button--primary {
  background: #3b82f6;
  border-color: #3b82f6;
}

.el-button--primary:hover {
  background: #2563eb;
  border-color: #2563eb;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
}

.el-button--success {
  background: #10b981;
  border-color: #10b981;
}

.el-button--success:hover {
  background: #059669;
  border-color: #059669;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
}

.el-button--warning {
  background: #f59e0b;
  border-color: #f59e0b;
}

.el-button--warning:hover {
  background: #d97706;
  border-color: #d97706;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(245, 158, 11, 0.3);
}

/* 输入框样式 */
.el-input {
  border-radius: 0;
}

.el-input :deep(.el-input__wrapper) {
  border: 2px solid #e2e8f0;
  border-radius: 0;
  box-shadow: none;
}

.el-input :deep(.el-input__wrapper:hover) {
  border-color: #3b82f6;
}

.el-input :deep(.el-input__wrapper.is-focus) {
  border-color: #3b82f6;
  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
}

/* 选择器样式 */
.el-select {
  border-radius: 0;
}

.el-select :deep(.el-input__wrapper) {
  border: 2px solid #e2e8f0;
  border-radius: 0;
  box-shadow: none;
}

.el-select :deep(.el-input__wrapper:hover) {
  border-color: #3b82f6;
}

.el-select :deep(.el-input__wrapper.is-focus) {
  border-color: #3b82f6;
  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
}

/* 分页样式 */
.el-pagination {
  border-radius: 0;
}

.el-pagination :deep(.el-pager li) {
  border-radius: 0;
  border: 2px solid #e2e8f0;
  margin: 0 2px;
  transition: all 0.3s ease;
}

.el-pagination :deep(.el-pager li:hover) {
  border-color: #3b82f6;
  color: #3b82f6;
}

.el-pagination :deep(.el-pager li.is-active) {
  background: #3b82f6;
  border-color: #3b82f6;
  color: #ffffff;
}

.el-pagination :deep(.btn-prev),
.el-pagination :deep(.btn-next) {
  border-radius: 0;
  border: 2px solid #e2e8f0;
  transition: all 0.3s ease;
}

.el-pagination :deep(.btn-prev:hover),
.el-pagination :deep(.btn-next:hover) {
  border-color: #3b82f6;
  color: #3b82f6;
}
</style>
